route.ts 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { NextRequest, NextResponse } from "next/server";
  2. async function handle(
  3. req: NextRequest,
  4. { params }: { params: { action: string; key: string[] } },
  5. ) {
  6. const requestUrl = new URL(req.url);
  7. const endpoint = requestUrl.searchParams.get("endpoint");
  8. if (req.method === "OPTIONS") {
  9. return NextResponse.json({ body: "OK" }, { status: 200 });
  10. }
  11. const [action, ...key] = params.key;
  12. // only allow to request to *.upstash.io
  13. if (!endpoint || !endpoint.endsWith("upstash.io")) {
  14. return NextResponse.json(
  15. {
  16. error: true,
  17. msg: "you are not allowed to request " + params.key.join("/"),
  18. },
  19. {
  20. status: 403,
  21. },
  22. );
  23. }
  24. // only allow upstash get and set method
  25. if (action !== "get" && action !== "set") {
  26. return NextResponse.json(
  27. {
  28. error: true,
  29. msg: "you are not allowed to request " + params.action,
  30. },
  31. {
  32. status: 403,
  33. },
  34. );
  35. }
  36. const [protocol, ...subpath] = params.key;
  37. const targetUrl = `${protocol}://${subpath.join("/")}`;
  38. const method = req.headers.get("method") ?? undefined;
  39. const shouldNotHaveBody = ["get", "head"].includes(
  40. method?.toLowerCase() ?? "",
  41. );
  42. const fetchOptions: RequestInit = {
  43. headers: {
  44. authorization: req.headers.get("authorization") ?? "",
  45. },
  46. body: shouldNotHaveBody ? null : req.body,
  47. method,
  48. // @ts-ignore
  49. duplex: "half",
  50. };
  51. const fetchResult = await fetch(targetUrl, fetchOptions);
  52. console.log("[Any Proxy]", targetUrl, {
  53. status: fetchResult.status,
  54. statusText: fetchResult.statusText,
  55. });
  56. return fetchResult;
  57. }
  58. export const POST = handle;
  59. export const GET = handle;
  60. export const OPTIONS = handle;
  61. export const runtime = "edge";